﻿using SerialPortTool;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace datatool
{
    public class DataDefs
    {
        public static string[] m_CommMsg = [
            "工作状态 （0静默，1待机，2发射）",
            "驻留长度 （步进0.1ms）",
            "工作频率1 （步进1MHz，默认8500MHz）",
            "工作频率2 （步进1MHz，默认8500MHz）",
            "电源加电控制 （输入0，不加电，输入7，6V，12V，100V依次加点时间间隔10us，第一次加点驻留周期留足够电源上电的时间）",
            "预留1",
            "频率源1发射脉冲个数 （80个）",
            "频率源1脉冲重复周期 （步进0.1us，最大值5000）",
            "频率源1波形脉宽 （步进1ns，默认500ns，最小值10ns，最大值65535ns）",
            "频率源1脉冲起始 （步进5ns，默认设置200，最小值0，最大值65535(327us)）",
            "频率源1预留",
            "频率源2发射脉冲个数 （80个）",
            "频率源2脉冲重复周期 （步进0.1us，最大值5000）",
            "频率源2波形脉宽 （步进1ns，默认500ns，最小值10ns，最大值65535ns）",
            "频率源2脉冲起始 （步进5ns，默认设置200，最小值0，最大值65535(327us)）",
            "频率源2预留",
            "T通道1脉冲起始 （步进5ns，默认设置200，最小值0，最大值65535(327us)）",
            "T通道1波形脉宽 （步进1ns，默认500ns，最小值10ns，最大值65535ns）",
            "T通道2脉冲起始 （步进5ns，默认设置200，最小值0，最大值65535(327us)）",
            "T通道2波形脉宽 （步进1ns，默认500ns，最小值10ns，最大值65535ns）",
            "备份",
            "T通道发射控制0~15",
            "T通道发射控制16~31",
            "T通道发射控制32~47",
            "T通道发射控制48~63",
            "T通道发射控制64~79",
            "T通道相位控制 （地址选择0到16）",
            "相位备份",
            "备份",
            "时间信息字1",
            "时间信息字2",
            "时间信息字3",
            "时间信息字4",
            "主机专用控制字",
            "主机专用控制字",
            "主机专用控制字",
            "主机专用控制字",
            "驻留计数1",
            "驻留计数2",
            "校验字1",
            "校验字2",
            "预留",
            "预留",
            "预留",
            "预留",
            "预留",
            "预留",
            "预留",
            "预留",
            "预留",
            "预留",
        ];
    }

    /// <summary>
    /// Interaction logic for MainProUC.xaml
    /// </summary>

    public partial class MainProUC : UserControl
    {
        private SerialPort _serialPort = new SerialPort();
        private Thread _receiveThread;

        private byte[] m_revBuffer = new byte[102];
        private int m_revIdx = 0;
        public ObservableCollection<int> BaudRates { get; } = new ObservableCollection<int>
        {9600, 19200, 38400, 57600, 115200 };

        public ObservableCollection<DataWord> DataWords { get; } = new ObservableCollection<DataWord>();

        public UInt16[] m_CMDDat =
        [
            0x0000,

            20,

            8500,
            8500,

            0x0000,

            0x0000,
            
            // FR 1
            3, 5000, 500, 200, 0x0000,
            // FR 1
            3, 5000, 500, 200, 0x0000,
            // T mod
            200, 500, 200, 500, 0x0000,

            // SCW8_1~5 天线阵面及波束控制
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
            
            // SCW8_6 T通道相位控制
            0x0000, 0x0000,

            //SCW8_8 备份
            0x0000,

            // 时间信息
            0x0000, 0x0000, 0x0000, 0x0000,

            // 主机专用控制字
            0x0000, 0x0000, 0x0000, 0x0000,

            // 驻留计数
            0x0000, 0x0000,

            // SCW12_1~2 校验字
            0x0000, 0x0000,

            // SCW13_1~10 预留
            0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        ];

        
        public MainProUC()
        {
            InitializeComponent();
            RefreshPorts();
            cmbPorts.SelectedIndex = 0;
            cmbBaudRate.ItemsSource = BaudRates;
            cmbBaudRate.SelectedIndex = 4;

            for (int i = 0; i < 51; i++)
                DataWords.Add(new DataWord { Address = i, Value = string.Format("{0:X04}", m_CMDDat[i]), CommMsg = DataDefs.m_CommMsg[i]});
            dgDataFrame.ItemsSource = DataWords;
        }

        private void RefreshPorts()
        {
            cmbPorts.Items.Clear();
            foreach (string port in SerialPort.GetPortNames())
            {
                cmbPorts.Items.Add(port);
            }
            if (cmbPorts.Items.Count > 0) cmbPorts.SelectedIndex = 0;
        }

        private void BtnOpen_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_serialPort.IsOpen)
                {
                    _serialPort.Close();
                    btnOpen.Content = "打开";
                    btnSend.IsEnabled = false;
                    Log("串口已关闭");
                }
                else
                {
                    _serialPort.PortName = cmbPorts.SelectedItem.ToString();
                    _serialPort.BaudRate = (int)cmbBaudRate.SelectedItem;
                    _serialPort.Open();
                    btnOpen.Content = "关闭";
                    btnSend.IsEnabled = true;
                    Log($"串口已打开 {_serialPort.PortName}@{_serialPort.BaudRate}");
                    StartReceiveThread();
                }
            }
            catch (Exception exp)
            {
                Log($"串口操作异常：{exp.Message}");
            }
        }

        private void BtnSend_Click(object sender, RoutedEventArgs e)
        {
            byte[] frame = new byte[102];
            for (int i = 0; i < 51; i++)
            {
                UInt16 value = Convert.ToUInt16(DataWords[i].Value, 16);
                frame[i * 2] = (byte)(value & 0xFF);
                frame[i * 2 + 1] = (byte)((value >> 8) & 0xFF);
            }
            m_revIdx = 0;
            _serialPort.Write(frame, 0, 102);
            Log($"发送帧: {BitConverter.ToString(frame)}");
        }

        private void StartReceiveThread()
        {
            _receiveThread = new Thread(() =>
            {
                while (_serialPort.IsOpen)
                {
                    try
                    {
                        int received = _serialPort.Read(m_revBuffer, m_revIdx, 102 - m_revIdx);
                        if(received > 0)
                        {
                            m_revIdx += received;
                        }

                        if (m_revIdx == 102)
                        {
                            Dispatcher.Invoke(() =>
                            {
                                Log($"收到帧: {BitConverter.ToString(m_revBuffer)}");
                            });

                            m_revIdx = 0;
                        }
                    }
                    catch (Exception ex)
                    {
                        Log($"接收错误: {ex.Message}");
                        break;
                    }
                }
            });
            _receiveThread.IsBackground = true;
            _receiveThread.Start();
        }

        private void Log(string message)
        {
            Dispatcher.Invoke(() =>
            {
                (Window.GetWindow(this) as MainWindow)?.AppendLog(message);
            });
        }

        private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            var scrollViewer = (ScrollViewer)sender;
            scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta);
            e.Handled = true;
        }

        private void btnRefresh_Click(object sender, RoutedEventArgs e)
        {
            RefreshPorts();
        }
    }

}
